package com.dc.gameserver.extComponents.ehcache;


import com.dc.gameserver.baseConfig.Config;
import com.dc.gameserver.extComponents.ehcache.Icache.CacheProvider;
import javolution.util.FastMap;
import net.sf.ehcache.CacheManager;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;


/**
 * Created with IntelliJ IDEA.
 * User: CLINUX
 * Date: 12-11-25
 * Time: 下午8:24
 * To change this template use File | Settings | File Templates.
 * Cache Provider plugin
 */
public class EhCacheProvider implements CacheProvider {

    private static final Log log = LogFactory.getLog(EhCacheProvider.class);

    /**ehcache manager*/
    private CacheManager manager;

    protected  EhCacheProvider(){}

    private FastMap<String, Ehcache> _CacheManager ;

    /**
     * Builds a Cache.
     * <p>
     * Even though this method provides properties, they are not used.
     * Properties for EHCache are specified in the ehcache.xml file.
     * Configuration will be read from ehcache.xml for a cache declaration
     * where the name attribute matches the name parameter in this builder.
     *
     * @param cachename the name of the cache. Must match a cache configured in ehcache.xml
     * @return a newly built cache will be built and initialised
     * @throws com.dc.gameserver.extComponents.ehcache.CacheException inter alia, if a cache of the same name already exists
     */
    public Ehcache buildCache(String cachename, boolean autoCreate) throws CacheException {
        try{
            Ehcache ehcache = _CacheManager.get(cachename); //cache  ==  Ehcache
            if(ehcache == null && autoCreate){
                try {
                    net.sf.ehcache.Cache cache = manager.getCache(cachename);    //获取cache
                    if (cache == null) {
                        log.warn("Could not find configuration [" + cachename + "]; using defaults.");
                        manager.addCache(cachename);
                        cache = manager.getCache(cachename);
                        log.debug("started EHCache region: " + cachename);
                    }
                    synchronized(_CacheManager){
                        ehcache = new Ehcache(cache);
                        _CacheManager.put(cachename, ehcache);
                        return ehcache ;
                    }
                }
                catch (net.sf.ehcache.CacheException e) {
                    throw new CacheException(e);
                }
            }
            return ehcache;
        }catch (Exception e){
            log.error(e);
        }

        return null;
    }

    /**
     * Callback to perform any necessary initialization of the underlying cache implementation
     * during SessionFactory construction.
     *
     */
    public void registerMemoryStore() throws CacheException {
        if (manager != null) {
            log.warn("Attempt to restart an already started EhCacheProvider. Use sessionFactory.close() " +
                    " between repeated calls to buildSessionFactory. Using previously created EhCacheProvider." +
                    " If this behaviour is required, consider using net.sf.ehcache.hibernate.SingletonEhCacheProvider.");
            return;
        }
        this.manager = new CacheManager(Config.DEFAULT_VALUE.FILE_PATH.EHCACHE);
        this._CacheManager = new FastMap<String, Ehcache>().shared();
    }

    /**
     * Callback to perform any necessary cleanup of the underlying cache implementation
     * during SessionFactory.close().
     */
    public void shutdown() {
        if (manager != null) {
            manager.shutdown();
            manager = null;
        }
    }

}
